package middleware

import (
	"context"
	"github.com/gin-gonic/gin"
	"github.com/golang-jwt/jwt/v5"
	"github.com/redis/go-redis/v9"
	"github.com/spf13/viper"
	ijwt "go-admin/server/internal/web/jwt"
	"net/http"
	"strconv"
	"strings"
)

var JwtAdmin jwtAdminRedisInfo

type jwtAdminRedisInfo struct {
	AdminID       int64  `json:"admin_id"`
	Email         string `json:"email"`
	Mobile        string `json:"mobile"`
	HeadSculpture string `json:"head_sculpture"`
	LoginName     string `json:"login_name"`
	AdminName     string `json:"admin_name"`
	UserType      string `json:"user_type"`
}

type LoginJWTMiddlewareBuilder struct {
	cmd redis.Cmdable
}

func NewLoginJWTMiddlewareBuilder(cmd redis.Cmdable) *LoginJWTMiddlewareBuilder {
	return &LoginJWTMiddlewareBuilder{
		cmd: cmd,
	}
}

func (l *LoginJWTMiddlewareBuilder) Build() gin.HandlerFunc {

	return func(ctx *gin.Context) {

		if IsPathPublic(ctx.Request.URL.Path) {
			return
		}
		//Token 获取处理
		tokenHeader := ctx.GetHeader("Authorization")
		if tokenHeader == "" {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		segs := strings.Split(tokenHeader, " ")
		if len(segs) != 2 {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}

		//Token 解析校验
		tokenStr := segs[1]
		claims := &ijwt.UserClaims{}
		token, err := jwt.ParseWithClaims(tokenStr, claims, func(token *jwt.Token) (interface{}, error) {
			return []byte(viper.GetString("jwt.admin")), nil
		})
		if err != nil {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		if token == nil || !token.Valid || claims.Iden == "" {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
		//获取用户信息
		l.findUserInfo(ctx, claims)
	}
}

func (l *LoginJWTMiddlewareBuilder) findUserInfo(ctx *gin.Context, claims *ijwt.UserClaims) {

	userJson, err := l.cmd.HGetAll(ctx, "admin:login:"+claims.Iden).Result()
	if err != nil {
		ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	}
	if mobile, ok := userJson["mobile"]; ok {
		JwtAdmin.Mobile = mobile
	}
	if userType, ok := userJson["user_type"]; ok {
		JwtAdmin.UserType = userType
	}
	if email, ok := userJson["email"]; ok {
		JwtAdmin.Email = email
	}
	if headSculpture, ok := userJson["head_sculpture"]; ok {
		JwtAdmin.HeadSculpture = headSculpture
	}
	if loginName, ok := userJson["login_name"]; ok {
		JwtAdmin.LoginName = loginName
	}
	if adminName, ok := userJson["admin_name"]; ok {
		JwtAdmin.AdminName = adminName
	}
	if adminID, ok := userJson["admin_id"]; !ok {
		ctx.AbortWithStatus(http.StatusUnauthorized)
		return
	} else {
		adminId, err := strconv.ParseInt(adminID, 10, 64)
		if err != nil {
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		JwtAdmin.AdminID = adminId
	}
	newCtx := context.WithValue(ctx.Request.Context(), "label", JwtAdmin.UserType)
	ctx.Request = ctx.Request.WithContext(newCtx)

}
